package MyGui;

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;

import Element.*;
import Element.Geom.*;
import DistSys.*;

public class EditTempDlg extends AbsElemInfoDlg implements WindowListener,
                                                           ActionListener {
    private JComboBox    comboType, comboName;
    private JTextArea    taDesc;
    private JCheckBox[]  checksFont;
    private JTextField[] tfsFont;
    private JButton      btnCopyTemp, btnDeleteTemp;

    private static final int[] GENERAL_INDEX = new int[] {
        AbsElem.DATA_ZONE,
        //AbsElem.DATA_LAYER,
        -1,  // separator
        AbsElem.DATA_CUSTOMERS,
        AbsElem.DATA_SRC_VOLT,
        AbsElem.DATA_CONST_POWER,
        AbsElem.DATA_PF_CONST_POWER,
        AbsElem.DATA_IS_LEADING,
        -1,  // separator
        AbsElem.DATA_RATED_POWER,
        AbsElem.DATA_RATED_CURR,
        -1,  // separator
        AbsElem.DATA_RECLOSING,
        AbsElem.DATA_INST_BLOCKED
    };

    private static final int[] REL_INDEX = new int[] {
        AbsElem.DATA_TEMP_FAULT,
        AbsElem.DATA_SUST_FAULT,
        AbsElem.DATA_OPEN_CKT,
        AbsElem.DATA_MTTR,
        AbsElem.DATA_MTTS,
        AbsElem.DATA_OPER_FAIL,
        -1,  // separator
        AbsElem.DATA_VOLT_SAG_LEVEL
    };

    private static final int[] PF_INDEX = new int[] {
        AbsElem.DATA_RESISTANCE,
        AbsElem.DATA_REACTANCE,
        AbsElem.DATA_SHUNT_COND,
        AbsElem.DATA_SHUNT_SUCEP,
        AbsElem.DATA_CONST_CURR,
        AbsElem.DATA_PF_CONST_CURR
    };

    private static final int[] ECON_INDEX = new int[] {
        AbsElem.DATA_CAPITAL_COST,
        AbsElem.DATA_OM_COST,
        AbsElem.DATA_COST_PER_INT_KW,
        AbsElem.DATA_COST_PER_INT_KWH,
        AbsElem.DATA_COST_PER_SAG
    };

    private static final int[] VOLTVAR_INDEX = new int[] {
        AbsElem.DATA_TXFM_RATIO,
        AbsElem.DATA_TAP_RATIO,
        AbsElem.DATA_NUM_BOOST,
        AbsElem.DATA_NUM_BUCK,
        AbsElem.DATA_BOOST_TRIG,
        AbsElem.DATA_BUCK_TRIG
    };

    private static final int[] MISC_INDEX = new int[] {
        AbsElem.DATA_PHASE,
        -1,  // separator
        AbsElem.DATA_OPTIMIZABLE,
        AbsElem.DATA_IN_OPT_LIB,
        -1,  // separator
        AbsElem.DATA_MAINT_RATE,
        AbsElem.DATA_MAINT_DUR
    };

    private static final int[] FONT_INDEX = new int[] {
        AbsElem.DATA_FONT_SIZE
    };

    public EditTempDlg(MainFrame parent, String title, boolean modal) {
        super(parent, title, modal,(AbsElem)Templates.subLists[0].elementAt(0));

        font = GuiConst.fontDefault;

        JPanel northPanel = createNorthPanel();
        JPanel centerPanel = createCenterPanel();
        JPanel southPanel = createSouthPanel();

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout(5, 5));
        contentPane.add(northPanel, BorderLayout.NORTH);
        contentPane.add(centerPanel, BorderLayout.CENTER);
        contentPane.add(southPanel, BorderLayout.SOUTH);

        this.addWindowListener(this);
        this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        this.setLocation(200, 200);
        this.setSize(440, 470);
        //this.setResizable(false);
        //this.setVisible(true);

        // Select comboType after everything is created.
        comboName.addActionListener(this);
        comboType.addActionListener(this);
        comboType.setSelectedIndex(0);
    }

    protected JPanel createDataPanel(int[] indices) {
        return createPanel(indices, " Data ", PANEL_DATA | PANEL_EDIT);
    }

    /*========================================
    Create three major panels:
        createNorthPanel()
        createCenterPanel()
        createSouthPanel()
    ========================================*/
    private JPanel createNorthPanel(){
        JPanel p = new JPanel();
        p.setLayout(MyDlgFrame.gridBagLayout);

        comboType = new JComboBox(SysConst.ssTemplType);
        comboName = new JComboBox();

        taDesc = new JTextArea(3, 15);
        taDesc.setInputVerifier(new InputVerifier() {
            public boolean verify(JComponent input) {
                bModified = true;
                elem.getElemGeomObj().setDesc(((JTextArea)input).getText());
                return true;
            }
        });
        taDesc.setLineWrap(true);
        taDesc.setWrapStyleWord(true);
        JScrollPane paneForDesc = new JScrollPane(taDesc);
        paneForDesc.setSize(200, 150);

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(3, 3, 3, 3);
        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridy=0; c.gridx=0; c.weightx = 0;
        p.add(new JLabel("Template Type:", JLabel.RIGHT), c);
        c.gridx=1; c.weightx = 1; p.add(comboType, c);

        c.gridy=1; c.gridx=0; c.weightx = 0;
        p.add(new JLabel("Template Name:", JLabel.RIGHT), c);
        c.gridx=1; c.weightx = 1; p.add(comboName, c);

        c.gridy=2; c.gridx=0; c.weightx = 0;
        p.add(new JLabel("Description:", JLabel.RIGHT), c);
        c.gridx=1; c.weightx = 1; c.gridheight = 2; p.add(paneForDesc, c);

        return p;
    }

    private JPanel createCenterPanel(){
        JPanel p = new JPanel();
        JTabbedPane tabbedPane = new JTabbedPane();

        tabbedPane.addTab("General", createTab(createDataPanel(GENERAL_INDEX)));
        tabbedPane.addTab("Reliability", createTab(createDataPanel(REL_INDEX)));
        tabbedPane.addTab("Power Flow", createTab(createDataPanel(PF_INDEX)));
        tabbedPane.addTab("Economics", createTab(createDataPanel(ECON_INDEX)));
        tabbedPane.addTab("Volt/Var", createTab(createDataPanel(VOLTVAR_INDEX)));
        if (SysConst.DEBUG_MODE > 0)
            tabbedPane.addTab("Misc", createTab(createDataPanel(MISC_INDEX)));
        tabbedPane.addTab("Text", createTab(createTextPanel()));

        recreateAllPanels();
        updateAll();

        //Add the tabbed pane to this panel.
        p.setLayout(new GridLayout(1, 1, 2, 2));
        p.add(tabbedPane);
        return p;
    }

    private JPanel createSouthPanel(){
        JPanel p = new JPanel();
        btnCopyTemp = new JButton("Copy Template");
        btnCopyTemp.addActionListener(this);
        btnDeleteTemp = new JButton("Delete Template");
        btnDeleteTemp.addActionListener(this);
        p.add(btnCopyTemp);
        p.add(btnDeleteTemp);
        return p;
    }

    private JPanel createTab(JPanel panel) {
        JPanel wrapper = new JPanel(MyDlgFrame.gridBagLayout);

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(GAP, GAP, GAP, GAP);
        c.anchor = GridBagConstraints.NORTH;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = c.weighty = 1;

        wrapper.add(panel, c);
        return wrapper;
    }

    private JPanel createTextPanel() {
        // tab text top
        tfsFont = new JTextField[] {
            new JTextField(6)
        };
        tfsFont[0].setHorizontalAlignment(JTextField.LEFT);
        checksFont = new JCheckBox[] { new JCheckBox(
            SysConst.getDataFieldFromValueIndex(AbsElem.DATA_FONT_SIZE))
        };
        tfsFont[0].addFocusListener(focusListener);
        tfsFont[0].setInputVerifier(new DataSaveVerifier(tfsFont, FONT_INDEX));
        checksFont[0].addActionListener(new CheckSaveActionListener(
            checksFont, tfsFont, FONT_INDEX));

        JPanel panel = new JPanel(MyDlgFrame.gridBagLayout);
        panel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " General "));
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(0, GAP, GAP, 0);
        c.anchor = GridBagConstraints.WEST;
        c.fill = GridBagConstraints.NONE;
        c.gridx = 0; c.gridy = 0; panel.add(checksFont[0], c);
        c.insets.right = GAP;
        c.gridx = 1; c.weightx = 1; panel.add(tfsFont[0], c);

        return panel;
    }

    protected void updateAll(){
        AbsElemGeom geom = elem.getElemGeomObj();

        // update north panel
        taDesc.setText(geom.getDesc());

        // update all panels
        updateAllPanels();

        // update tab Text
        boolean bFlag = elem.getCustomizedFlag(AbsElem.DATA_FONT_SIZE);
        checksFont[0].setSelected(bFlag);
        tfsFont[0].setEnabled(bFlag);
        tfsFont[0].setText(nf.format(elem.getData(AbsElem.DATA_FONT_SIZE)));
    }

    /*======================================
    Implement WindowListener interfaces
    ======================================*/
    public void windowOpened( WindowEvent evt ){ }
    public void windowClosed( WindowEvent evt ){ }
    public void windowIconified( WindowEvent evt ){ }
    public void windowDeiconified( WindowEvent evt ){ }
    public void windowActivated( WindowEvent evt ){ }
    public void windowDeactivated( WindowEvent evt ){ }

    public void windowClosing( WindowEvent evt ){
        if (verifyFocus()) {
            updateAllElements();
            hide();
        }
    }

    //ActionListener
    public void actionPerformed(ActionEvent evt){
        Object o = evt.getSource();
        if (o == comboType) {
            int iType = SysConst.mapIndexToTemplType(comboType.getSelectedIndex());
            if (iType >= 0 && verifyFocus()) {
                comboName.setModel(
                    new DefaultComboBoxModel(Templates.nameLists[iType]));
                // comboName selects index 0 automatically
            }
        } else if (o == comboName) {
            int iName = comboName.getSelectedIndex();
            if (iName >= 0 && verifyFocus()) {
                // Since the dropdown list of comboType will cover comboName,
                // so comboName will be triggered everytime when an item in
                // comboType is selected. In this case, iName = -1.
                int iType = SysConst.mapIndexToTemplType(comboType.getSelectedIndex());

                updateAllElements();
                elem = (AbsElem)Templates.subLists[iType].elementAt(iName);
                recreateAllPanels();
                updateAll();

                String sName = elem.getElemGeomObj().getName();
                for (int i = 0; i < SysConst.ssGenericTemplName.length; i++) {
                    if (sName.equals(SysConst.ssGenericTemplName[i])) {
                        btnDeleteTemp.setEnabled(false);
                        return;
                    }
                }
                btnDeleteTemp.setEnabled(true);
            }
        } else if (o == btnCopyTemp) {
            if (verifyFocus()) {
                updateAllElements();

                String newName = elem.getElemGeomObj().getName();
                int iDummy = 0;
                do {
                    newName = (String)JOptionPane.showInputDialog(this,
                        "Please enter the name for the new template:",
                        getTitle(), JOptionPane.QUESTION_MESSAGE, null, null,
                        newName);
                    if (newName == null)
                        return;  // user canceled

                    for (iDummy = 0; iDummy < SysConst.MAX_TEMPLTYPE; iDummy++){
                        if (Templates.nameLists[iDummy].contains(newName))
                            break;
                    }
                } while (iDummy < SysConst.MAX_TEMPLTYPE);

                AbsElem newElem = (AbsElem)elem.clone();
                newElem.getElemGeomObj().setName(newName);
                Templates.insertIntoWithReplaceTempList(newElem);
                // Syncronize all accompanying elements
                for (int i = 0; i < Sys.elemList.size(); i++) {
                    AbsElem absElem = (AbsElem)Sys.elemList.elementAt(i);
                    if (absElem.getDftTemp() == null &&
                        newName.equals(absElem.getDftTempName())) {
                        absElem.setDftTemp(newElem);
                        Templates.copyAllDataFromTemp(absElem, newElem);
                    }
                }

                comboName.setModel(new DefaultComboBoxModel(
                    Templates.nameLists[elem.getType()]));
                comboName.setSelectedItem(newName);
            }
        } else if (o == btnDeleteTemp) {
            // Count number of times this template is used.
            int iCount = 0;
            for (int i = 0; i < Sys.elemList.size(); i++) {
                if (elem.equals(((AbsElem)Sys.elemList.elementAt(i)).getDftTemp()))
                    iCount++;
            }
            boolean bConfirmation = false;
            if (iCount > 0) {
                bConfirmation = (JOptionPane.showConfirmDialog(this,
                    "This template is used in " + iCount + " element" +
                    (iCount > 1 ? "s":"")+".\nDo you really want to delete it?",
                    getTitle(), JOptionPane.YES_NO_OPTION,
                    JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION);
            } else {
                bConfirmation = (JOptionPane.showConfirmDialog(this,
                    "This template is unused.\nDo you want to delete it?",
                    getTitle(), JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION);
            }

            if (bConfirmation) {
                Templates.remove(elem);

                // Syncronize all accompanying elements
                if (iCount > 0) {
                    for (int i = 0; i < Sys.elemList.size(); i++) {
                        AbsElem absElem = (AbsElem)Sys.elemList.elementAt(i);
                        if (elem.equals(absElem.getDftTemp()))
                            absElem.setDftTemp((AbsElem)null);
                    }
                }
                // Check active templates
                iCount = Sys.prjInfo.checkActiveTemp(elem);
                if (iCount > 0)
                    JOptionPane.showMessageDialog(this, ""+iCount +
                        " active template"+(iCount > 1 ? "s have":" has") +
                        " been changed to a default value.", getTitle(),
                        JOptionPane.INFORMATION_MESSAGE);

                comboName.setModel(new DefaultComboBoxModel(
                    Templates.nameLists[elem.getType()]));
            }
        }
    }//end of actionPerformed();

    private void updateAllElements() {
        if (bModified) {
            for (int i = 0; i < Sys.elemList.size(); i++) {
                AbsElem absElem = (AbsElem)Sys.elemList.elementAt(i);
                if (elem.equals(absElem.getDftTemp())) {
                    Templates.copyAllDataFromTemp(absElem, elem);
                }
            }
        }
    }
}
